﻿
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Runtime.CompilerServices;
    using System.Threading;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Controls.Primitives;
    using System.Windows.Media;
    using System.Windows.Threading;
        using System.Text;
namespace WCYCReader.Utility
{
    public static class MemoryDiagnosticsHelper
    {
        private static bool alreadyFailedPeak = false;
        private static TextBlock currentMemoryBlock;
        private static bool forceGc;
        private static int lastSafetyBand = -1;
        private const long MAX_CHECKPOINTS = 10L;
        private const long MAX_MEMORY = 0x7800000L;
        private static TextBlock peakMemoryBlock;
        private static Popup popup;
        private static Queue<MemoryCheckpoint> recentCheckpoints;
        private static DispatcherTimer timer;

        [Conditional("DEBUG")]
        public static void Checkpoint(string text)
        {
            if (recentCheckpoints != null)
            {
                if (recentCheckpoints.Count >= 9L)
                {
                    recentCheckpoints.Dequeue();
                }
                recentCheckpoints.Enqueue(new MemoryCheckpoint(text, GetCurrentMemoryUsage()));
            }
        }

        private static Brush GetBrushForSafetyBand(int safetyBand)
        {
            switch (safetyBand)
            {
                case 0:
                    return new SolidColorBrush(Colors.Green);

                case 1:
                    return new SolidColorBrush(Colors.Orange);
            }
            return new SolidColorBrush(Colors.Red);
        }

        public static long GetCurrentMemoryUsage()
        {
            return 0L;
        }

        public static long GetPeakMemoryUsage()
        {
            return 0L;
        }

        private static int GetSafetyBand(long mem)
        {
            double num = ((double) mem) / 125829120.0;
            if (num <= 0.75)
            {
                return 0;
            }
            if (num <= 0.9)
            {
                return 1;
            }
            return 2;
        }

        private static void HidePopup()
        {
            popup.IsOpen=(false);
            popup = null;
        }

        private static void ShowPopup()
        {
            MemoryDiagnosticsHelper.popup = new Popup();
            double item = (double)Application.Current.Resources["PhoneFontSizeSmall"] - 2;
            Brush brush = (Brush)Application.Current.Resources["PhoneForegroundBrush"];
            StackPanel stackPanel = new StackPanel()
            {
                Orientation = Orientation.Horizontal,
                Background = (Brush)Application.Current.Resources["PhoneSemitransparentBrush"]
            };
            StackPanel stackPanel1 = stackPanel;
            TextBlock textBlock = new TextBlock()
            {
                Text = "---",
                FontSize = item,
                Foreground = brush
            };
            MemoryDiagnosticsHelper.currentMemoryBlock = textBlock;
            TextBlock textBlock1 = new TextBlock()
            {
                Text = "",
                FontSize = item,
                Foreground = brush,
                Margin = new Thickness(5, 0, 0, 0)
            };
            MemoryDiagnosticsHelper.peakMemoryBlock = textBlock1;
            stackPanel1.Children.Add(MemoryDiagnosticsHelper.currentMemoryBlock);
            UIElementCollection children = stackPanel1.Children;
            TextBlock textBlock2 = new TextBlock()
            {
                Text = " kb",
                FontSize = item,
                Foreground = brush
            };
            ((PresentationFrameworkCollection<UIElement>)children).Add(textBlock2);
            stackPanel1.Children.Add(MemoryDiagnosticsHelper.peakMemoryBlock);
            CompositeTransform compositeTransform = new CompositeTransform()
            {
                Rotation = 90,
                TranslateX = 480,
                TranslateY = 425,
                CenterX = 0,
                CenterY = 0
            };
            stackPanel1.RenderTransform = compositeTransform;
            MemoryDiagnosticsHelper.popup.Child = stackPanel1;
            MemoryDiagnosticsHelper.popup.IsOpen = true;
        }

        [Conditional("DEBUG")]
        public static void Start(TimeSpan timespan, bool forceGc)
        {
            if (timer != null)
            {
                throw new InvalidOperationException("Diagnostics already running");
            }
            MemoryDiagnosticsHelper.forceGc = forceGc;
            recentCheckpoints = new Queue<MemoryCheckpoint>();
            StartTimer(timespan);
            ShowPopup();
        }

        private static void StartTimer(TimeSpan timespan)
        {
            MemoryDiagnosticsHelper.timer = new DispatcherTimer()
            {
                Interval = timespan
            };
            MemoryDiagnosticsHelper.timer.Tick += new EventHandler(MemoryDiagnosticsHelper.timer_Tick);
            MemoryDiagnosticsHelper.timer.Start();
        }

        [Conditional("DEBUG")]
        public static void Stop()
        {
            HidePopup();
            StopTimer();
            recentCheckpoints = null;
        }

        private static void StopTimer()
        {
            timer.Stop();
            timer = null;
        }

        private static void timer_Tick(object sender, EventArgs e)
        {
            if (forceGc)
            {
                GC.Collect();
            }
            UpdateCurrentMemoryUsage();
            UpdatePeakMemoryUsage();
        }

        private static void UpdateCurrentMemoryUsage()
        {
            long currentMemoryUsage = GetCurrentMemoryUsage();
            currentMemoryBlock.Text=(string.Format("{0:N}", currentMemoryUsage / 0x400L));
            int safetyBand = GetSafetyBand(currentMemoryUsage);
            if (safetyBand != lastSafetyBand)
            {
                currentMemoryBlock.Foreground=(GetBrushForSafetyBand(safetyBand));
                lastSafetyBand = safetyBand;
            }
        }

        private static void UpdatePeakMemoryUsage()
        {
            if (!alreadyFailedPeak && (GetPeakMemoryUsage() >= 125829120L))
            {
                alreadyFailedPeak = true;
                peakMemoryBlock.Text=("FAIL!");
                peakMemoryBlock.Foreground=(new SolidColorBrush(Colors.Red));
                bool isAttached = Debugger.IsAttached;
            }
        }

        public static IEnumerable<MemoryCheckpoint> RecentCheckpoints
        {
            get
            {
                if (recentCheckpoints != null)
                {
                    foreach (MemoryCheckpoint iteratorVariable0 in recentCheckpoints)
                    {
                        yield return iteratorVariable0;
                    }
                }
            }
        }

    }
}

